/**
 * 右鍵菜單插件
 * @author Ly
 * @version 1.0a
 */

/**
 * Ly.ContextMenu的構造函數
 * @param {Object} config 配置信息
 * config = {
	 itemSize : 0,                          // 顯示的項目數，若大於此數則顯示上下箭頭，如同系統的個性化菜單
	 events : {}                            // 公共事件集合
 }
 */
Ly.ContextMenu = function(config /* Object */) {
	var _this = this;
	this._config = {
		itemSize : config.itemSize || 0,
		events   : config.events || {},
		/**
		 * list = [
			level : 0,          // 此窗口的等級，即第幾級菜單
			container : obj,    // 容器對象
			items : []          // 菜單項
		]
		 */
		list : [],
		status : {}
	};
	this._private = {
		/**
		 * 根據菜單容器對象獲取菜單容器級別
		 * @param {Object} container 菜單容器對象
		 * @return {Number} 返回level，若未找到container則返回-1
		 */
		getLevelByContainer : function(container /* Object */) {
			var _list = _this._config.list;
			
			for (var i = 0, len = _list.length; i < len; ++i) {
				if (_list[i].container == container) {
					return _list[i].level;
				}
			}
			return -1;
		},
		
		// 獲取第一級菜單的容器對象，若不存在則創建
		getFirstLevelMenuContainer : function() {
			var _list = _this._config.list;
			
			for (var i = 0, len = _list.length; i < len; ++i) {
				if (_list[i].level == 0) {
					return _list[i].container;
				}
			}
			
			// 不存在，創建并保存
			var _container = Ly.createElement('div', { cls : 'ly-contextmenu-container' });
			_list.push({
				level     : 0,
				container : _container,
				items     : []
			});
			return _container;
		},
		
		/**
		 * 獲取obj的容器
		 * @param {Object} obj 菜單項
		 * @return {Object} 菜單項容器
		 */
		getMenuContainerByParentItem : function(obj /* Object */) {
			if (obj.subMenuContainer) {
				return obj.subMenuContainer;
			} else {
				var _container = Ly.createElement('div', { cls : 'ly-contextmenu-container' });
				_this._config.list.push({
					level     : this.getLevelByContainer(obj.container) + 1,
					container : _container,
					items     : []
				});
			}
		},
		
		/**
		 * 保存菜單項參數
		 * @param {Object} config 配置信息
		 */
		saveData : function(config /* Object */) {
			var _list = _this._config.list,
				_obj = {
					id                   : config.id,                     // 菜單項id
					name                 : config.name,                   // 菜單項名稱
					data                 : config.data,                   // 菜單項附加數據
					container            : config.container,              // 當前菜單項的容器
					parentItem           : config.parentItem,             // 菜單項的父菜單
					itemObject           : config.itemObject,             // 菜單項對象，此對象的innerHTML才是真正的菜單內容
					keepState            : config.keepState,              // 是否保持狀態，即是否選中時顯示對勾
					hasSubMenu           : false,                         // 是否擁有子菜單，默認為false
					disabled             : config.disabled,               // 是否禁用當前菜單項
					disabledPublicEvents : config.disabledPublicEvents    // 是否禁用公共事件
				};
			
			for (var i = 0, len = _list.length; i < len; ++i) {
				if (_list[i].container == container) {
					_list[i].push(_obj);
					break;
				}
			}
			this.modifyItem(_obj.parentItem.id, { hasSubMenu : true, subMenuContainer : container });
			return _obj;
		},
		
		/**
		 * 載入動作，即onmouseover/onmouseout事件
		 */
		loadActive : function(obj /* Object */) {
			Ly.addEvent('onmouseover', function(obj) {
				obj.className = 'ly-contextmenu-item-container';
				
			}, obj);
		},
		
		/**
		 * 添加菜單項
		 * @param {Object} config 配置信息，參見Ly.ContextMenu.prototype.add
		 */
		addItem : function(config /* Object */) {
			var _container;
			
			config.id = 'ly-contextmenu-' + Ly.getCount();
			config.itemObject = Ly.createElement('div', {
				cls : 'ly-contextmenu-item-container',
				innerHTML : '<table border="0" cellspacing="0" cellpadding="0" class="ly-contextmenu-item-table">' +
							'<tr>' +
							'<td id="' + config.id + '-left" class="ly-contextmenu-item-left"></td>' +
							'<td id="' + config.id + '-center" class="ly-contextmenu-item-center"></td>' +
							'<td id="' + config.id + '-right" class="ly-contextmenu-item-right"></td>' +
							'</tr>' +
							'</table>'
			});
			
			Ly.get(config.id + '-center').innerHTML = config.name;
			config.cls && (config.itemObject.className = 'ly-contextmenu-item-container ' + config.cls);
			config.style && (config.itemObject.cssText += ';' + config.style);
			config.disabled && (config.itemObject.className = 'ly-contextmenu-item-disabled');
			
			if (!_container.parentItem) {
				config.container = this.getFirstLevelMenuCotainer();
			} else {
				config.container = this.getMenuContainerByParentItem(config.parentItem);
			}
			
			if (config.insertBefore) {
				config.container.insertBefore(config.itemObject, config.insertBefore);
			} else {
				config.container.appendChild(config.itemObject);
			}
			
			!config.disabled && this.loadActive(config.itemObject);  // 非禁用狀態載入動作，即onmouseover/onmouseout
			!config.disabledPublicEvents && this.loadPublicEvents(config.itemObject);
			this.loadPrivateEvents(config.itemObject, config.events);
			
			return this.saveData(_container, config);
		},
		modifyItem : function(id /* String */, config /* Object */) {
		},
		removeItem : function(id /* String */) {
		},
		getMenuItemById : function(id /* String */) {
		}
	};
};
Ly.ContextMenu.prototype = {
	ver : '1.0a',
	
	/**
	 * 添加菜單項
	 * @param {Object} config 菜單項信息
	 * config = {
		 name : 'item',                     // 菜單項名稱
		 data : '',                         // 附加數據
		 parentItem : obj,                  // 父菜單項，即此菜單項作為誰的子菜單，默認則為一級菜單
		 keepState : false,                 // 是否保持狀態，即當選中過一次則在菜單項前面顯示對勾，再次選中取消
		 insertBefore : obj,                // 插入到某菜單之前，省略即添加到最後
		 disabled : false,                  // 當前菜單項是否禁用，默認false
		 style : '',                        // 菜單項的私有樣式
		 cls : '',                          // 菜單項的私有class樣式名稱
		 events : {},                       // 菜單項私有事件，可以包含click,dblclick等等
		 disabledPublicEvents : false       // 是否禁用公有事件，即在實例化類時所指定的事件
	 }
	 */
	add : function(config /* Object */) {
		var _config = {
			name                 : config.name,
			data                 : config.data,
			parentItem           : config.parentItem || null,
			keepState            : config.keepState || false,
			insertBefore         : config.insertBefore || null,
			disabled             : config.disabled || false,
			style                : config.style || '',
			cls                  : config.cls || '',
			events               : config.events || {},
			disabledPublicEvents : config.disabledPublicEvents || false
		};
		if (typeof _config.name == 'undefined') {
			alert('菜单名称不可为空');
			return this;
		}
		return this._private.addItem(_config);
	},
	
	/**
	 * 修改菜单项，对于传递的参数不赋初始值，在修改时对比原始值
	 * @param {Object} config 配置信息
	 * @param {String} id 要修改的菜单项id，可以是菜单项对象
	 * config = {
		 name : 'item',                     // 菜單項名稱
		 data : '',                         // 附加數據
		 parentItem : null,                 // 父菜單項，即此菜單項作為誰的子菜單，null則為一級菜單
		 keepState : false,                 // 是否保持狀態，即當選中過一次則在菜單項前面顯示對勾，再次選中取消
		 insertBefore : null,               // 插入到某菜單之前，默認為null，即添加到最後
		 disabled : false,                  // 當前菜單項是否禁用，默認false
		 style : '',                        // 菜單項的私有樣式
		 cls : '',                          // 菜單項的私有class樣式名稱
		 events : {},                       // 菜單項私有事件，可以包含click,dblclick等等
		 disabledPublicEvents : false       // 是否禁用公有事件，即在實例化類時所指定的事件
	 }
	 */
	modify : function(id /* String */, config /* Object */) {
		return this._private.modifyItem(id, config);
	},
	
	/**
	 * 删除指定的菜单项
	 * @param {String} id 要删除的菜单项id，可以传递菜单项对象
	 */
	remove : function(id /* String */) {
		return this._private.removeItem(id);
	},
	
	/**
	 * 添加分隔线
	 * @param {Object} config 配置信息
	 * config = {
		 menu : obj,                        // 要添加分隔线的菜单
		 insertBefore : null                // 插入在某菜单项的位置，默认为null（插入到最后）
	 }
	 */
	addSeparator : function(config /* Object */) {
		var _config = {
			menu         : config.menu,
			insertBefore : config.insertBefore || null
		};
		this._private.addItem(_config);
		return this;
	},
	
	/**
	 * 按id获取菜单项对象
	 * @param {String} id 要获取的菜单项id
	 */
	getMenuItemById : function(id /* String */) {
		id = id || '';
		if (id) {
			alert('ID值不合法！');
			return null;
		}
		return this._private.getMenuItemById(id);
	}
};